package com.ljx.itbbs.server.article.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.ljx.itbbs.common.constant.CacheConstants;
import com.ljx.itbbs.common.domain.entity.UserEntity;
import com.ljx.itbbs.common.utils.RedisUtil;
import com.ljx.itbbs.server.article.dao.PlateDao;
import com.ljx.itbbs.server.article.domain.entity.PlateEntity;
import com.ljx.itbbs.server.article.domain.vo.req.admin.PlateAdminSaveReq;
import com.ljx.itbbs.server.article.domain.vo.req.admin.PlateAdminUpdateReq;
import com.ljx.itbbs.server.article.domain.vo.resp.PlateResp;
import com.ljx.itbbs.server.article.domain.vo.resp.admin.PlateAdminResp;
import com.ljx.itbbs.server.article.domain.vo.resp.admin.PlaterQueryResp;
import com.ljx.itbbs.server.article.service.PlateService;
import com.ljx.itbbs.server.article.service.adapter.ArticleAdapter;
import com.ljx.itbbs.server.user.domain.dto.UserPlaterDto;
import com.ljx.itbbs.server.user.domain.entity.UserPlateRelationEntity;
import com.ljx.itbbs.server.user.service.UserPlateRelationService;
import com.ljx.itbbs.server.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class PlateServiceImpl implements PlateService {

    @Autowired
    private PlateDao plateDao;

    @Autowired
    private UserPlateRelationService userPlateRelationService;

    @Autowired
    private UserService userService;

    @Override
    public List<PlateResp> getAllPlate() {
        String key = CacheConstants.getKey(CacheConstants.PLATE_ALL);
        String allPlateStr = RedisUtil.get(key);
        if (StrUtil.isNotBlank(allPlateStr)){
            return JSONUtil.toList(allPlateStr, PlateResp.class);
        }
        List<PlateResp> allPlate = plateDao.getAllPlate();
        RedisUtil.set(key, allPlate, CacheConstants.PLATE_ALL_EXPIRE, TimeUnit.HOURS);

        return allPlate;
    }

    @Override
    public List<PlateAdminResp> adminPlateList() {
        return plateDao.adminPlateList();
    }

    @Override
    public void adminUpdatePlate(PlateAdminUpdateReq req) {
        plateDao.adminUpdatePlate(req);
    }

    @Override
    public void adminSavePlate(PlateAdminSaveReq req) {
        plateDao.save(ArticleAdapter.buildPlateSave(req));
    }

    @Override
    public void adminUpdatePlaterList(UserPlaterDto build) {
        PlateEntity plate = plateDao.getById(build.getPlateId());
        List<PlateResp.UserInfo> list = JSONUtil.toList(plate.getPlaterList(), PlateResp.UserInfo.class);
        list.add(ArticleAdapter.buildPlateUserInfo(build.getUid(), build.getNickname()));
        plate.setPlaterList(JSONUtil.toJsonStr(list));
        plateDao.updateById(plate);
    }

    @Override
    public List<PlaterQueryResp> adminQueryPlaterList(Long plateId) {
        List<UserPlateRelationEntity> plateList = userPlateRelationService.getPlateListByPlateId(plateId);
        // 获取用户信息
        List<Long> userIds = plateList.stream().map(UserPlateRelationEntity::getUid).collect(Collectors.toList());
        Map<Long, UserEntity> userMaps = userService.getUserInfoByIds(userIds);
        // 组合返回信息
        return plateList.stream().map(item -> {
            UserEntity user = userMaps.get(item.getUid());
            PlaterQueryResp platerQueryResp = new PlaterQueryResp();
            platerQueryResp.setId(item.getUid());
            platerQueryResp.setNickname(user.getNickname());
            platerQueryResp.setAvatar(user.getAvatar());
            return platerQueryResp;
        }).collect(Collectors.toList());
    }

    @Override
    public void adminCancelPlater(Long uid, Long plateId) {
        PlateEntity plate = plateDao.getById(plateId);
        List<PlateResp.UserInfo> list = JSONUtil.toList(plate.getPlaterList(), PlateResp.UserInfo.class);
        List<PlateResp.UserInfo> resList = list.stream().filter(item -> item.getId().equals(uid)).collect(Collectors.toList());
        plate.setPlaterList(JSONUtil.toJsonStr(resList));
        plateDao.updateById(plate);
    }
}
